package com.xiemu.ironman.core.service.impl;

import com.xiemu.ironman.core.utils.DeployUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.Set;

@Service("springDsImpl")
public class SpringHotDeployServiceImpl extends AbstractHotDeployServiceImpl {

    @Autowired ApplicationContext applicationContext;

    @Value("${hot.deploy.jar.file.path}")
    private String jarAddress;

    public SpringHotDeployServiceImpl(ApplicationContext applicationContext) {
        super(applicationContext);
    }

    /** 加入jar包后 动态注册bean到spring容器，包括bean的依赖 */
    public void hotDeploy(String jarName, String implClassName) {
        try {
            DefaultListableBeanFactory defaultListableBeanFactory =
                    (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
            String jarPth = DeployUtils.getJarPth(jarAddress, jarName);

          //  deletejar(jarName);
            Set<String> classNameSet = DeployUtils.readJarFile(jarAddress +jarName);
            URLClassLoader urlClassLoader =
                    new URLClassLoader(
                            new URL[] {new URL(jarPth)},
                            Thread.currentThread().getContextClassLoader());
            for (String className : classNameSet) {
                Class clazz = urlClassLoader.loadClass(className);
                if (DeployUtils.isSpringBeanClass(clazz)) {
                    BeanDefinitionBuilder beanDefinitionBuilder =
                            BeanDefinitionBuilder.genericBeanDefinition(clazz);
                    String beanName = DeployUtils.transformName(className);
                    boolean b = defaultListableBeanFactory.containsBean(beanName);
                    if(b){
                        defaultListableBeanFactory.removeBeanDefinition(beanName);
                    }
                    defaultListableBeanFactory.registerBeanDefinition(
                            beanName,
                            beanDefinitionBuilder.getBeanDefinition());
                }

            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deletejar(String jarName) {
        String jarPth = DeployUtils.getJarPth(jarAddress, jarName);
        try {
            super.delete(jarAddress+ jarName, jarPth);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
